﻿using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using LFSRecord2.Model;
using LFSRecord2.Model.Media;
using System.IO;
using LFSRecord2.Model.Replay;
using System.Diagnostics;
using System;
using LFSRecord2.Events;

namespace LFSRecord2.View.TimelineStructures
{
    /// <summary>
    /// Interaction logic for ReplayPlayerValueEditControl.xaml
    /// </summary>
    public partial class RDIdentValueEditControl : UserControl, INotifyPropertyChanged
    {
        public string ValueName = "";
        public int MaxLength = 63;

        public static DependencyProperty ValueProperty = DependencyProperty.Register(
              "Value",
              typeof(RDIdent),
              typeof(RDIdentValueEditControl),
              new FrameworkPropertyMetadata(new PropertyChangedCallback(handleValueChange))
            );
        public RDIdent Value
        {
            get
            {
                return (RDIdent)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
                OnPropertyChanged(ValueName);
            }
        }
        static void handleValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((RDIdentValueEditControl)d).writeLabelValue();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }

        public RDIdentValueEditControl()
        {
            InitializeComponent();
        }

        public void writeLabelValue()
        {
            Debug.WriteLine("Value of name : " + Value.PlayerName);
            // Check length of the text. Can be max 120px wide.
            string mediaName = Path.GetFileNameWithoutExtension(Value.ReplayFilePath);
            string playerName = Value.PlayerName;
            string str = "";
            FormattedText formattedText;

            // Media Object part
            for (int a = 0; a < mediaName.Length; a++)
            {
                str = str + "" + mediaName.ElementAt(a);

                formattedText = new FormattedText(
                    str,
                    CultureInfo.InvariantCulture,
                    FlowDirection.LeftToRight,
                    new Typeface("Segoe UI"),
                    10,
                    Brushes.Black);
                if (formattedText.Width > 62 && mediaName.Length > a + 2)
                {
                    str = str + " ...";
                    break;
                }
            }

            if (str.Length > 0)
                str = str + " -> ";

            // Playername part
            for (int a = 0; a < playerName.Length; a++)
            {
                str = str + "" + playerName.Substring(a, 1);

                formattedText = new FormattedText(
                    str,
                    CultureInfo.InvariantCulture,
                    FlowDirection.LeftToRight,
                    new Typeface("Segoe UI"),
                    10,
                    Brushes.Black);
                if (formattedText.Width > 142 && playerName.Length > a + 2)
                {
                    str = str + " ...";
                    break;
                }
            }

            ValueLabel.Text = (str.Length == 0) ? "..." : str;
            ValueLabel.ToolTip = mediaName + " -> " + playerName;
        }

        //string _origValue;
        private void ValueLabel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;

            int mediaIndex = -1, playerIndex;
            MenuItem mi, mi2;
            ContextMenu cm = new ContextMenu();
            CompLayerPropertyRDIdent prop = (CompLayerPropertyRDIdent)DataContext;
            RDIdent curRDIdent = prop.CurrentValue;
            MediaReplayData mrd;

            // Display a context menu, allowing the user to select replay and player
            ContextMenu = null;

            if (LfsRecordController.project.NumMediaOfType(MediaTypes.ReplayData) == 0)
            {
                mi = new MenuItem();
                mi.Name = "NoData";
                mi.Header = "No Replay Data Objects";
                mi.IsEnabled = false;
                cm.Items.Add(mi);
            }
            else
            {
                foreach (MediaBase mb in LfsRecordController.project.MediaObjects)
                {
                    mediaIndex++;
                    if (mb.MediaType != MediaTypes.ReplayData)
                    {
                        continue;
                    }
                    mrd = (MediaReplayData)mb;

                    mi = new MenuItem();
                    mi.Name = "RD" + mediaIndex;
                    mi.Header = Path.GetFileNameWithoutExtension(mb.FilePath);
                    mi.IsChecked = (curRDIdent.ReplayFilePath == mrd.FilePath) ? true : false;

                    playerIndex = 0;
                    foreach (ReplayPlayerData rpd in mrd.RData.Players)
                    {
                        mi2 = new MenuItem();
                        mi2.Name = "RDP" + playerIndex;
                        mi2.Header = rpd.PlayerName;
                        mi2.Command = RDIdentSelectCommand;
                        mi2.CommandParameter = new Point(mediaIndex, playerIndex);
                        mi2.IsChecked = (curRDIdent.ReplayFilePath == mrd.FilePath && curRDIdent.PlayerName == rpd.PlayerName) ? true : false;
                        mi.Items.Add(mi2);

                        playerIndex++;
                    }

                    cm.Items.Add(mi);
                }
            }

            //Debug.WriteLine("Showing context menu");
            ContextMenu = cm;
            ContextMenu.IsOpen = true;
            ContextMenu.Closed += new RoutedEventHandler(ContextMenu_Closed);
        }

        void ContextMenu_Closed(object sender, RoutedEventArgs e)
        {
            ContextMenu = null;
        }

        private void ValueLabel_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            if (ContextMenu != null)
            {
                ContextMenu.IsOpen = false;
                ContextMenu = null;
            }
        }

        // ReloadMediaCommand
        RelayCommand _rdIdentSelectCommand;
        public ICommand RDIdentSelectCommand
        {
            get
            {
                if (_rdIdentSelectCommand == null)
                    _rdIdentSelectCommand = new RelayCommand(param => this.RDIdentSelectCommandExecute(param));
                return _rdIdentSelectCommand;
            }
        }
        void RDIdentSelectCommandExecute(object param)
        {
            //CompLayerPropertyRDIdent prop = (CompLayerPropertyRDIdent)DataContext;
            Point indexes = (Point)param;
            MediaReplayData mb = (MediaReplayData)LfsRecordController.project.MediaObjects[(int)indexes.X];

            Debug.WriteLine("Selecting media object {0}, player {1}, name " + mb.RData.Players[(int)indexes.Y].PlayerName, indexes.X, indexes.Y);

            RDIdent oldValue = Value;
            Value = new RDIdent(mb.FilePath, mb.RData.Players[(int)indexes.Y].PlayerName, (int)indexes.Y);

            //if (oldValue.ReplayFilePath != Value.ReplayFilePath &&
            //    oldValue.PlayerName != Value.PlayerName)
            //{
                OnRDIdentValueChanged(new RDIdentValueChangedEventArgs(oldValue, Value));
            //}
        }

        public event EventHandler<RDIdentValueChangedEventArgs> RDIdentValueChanged;

        public virtual void OnRDIdentValueChanged(RDIdentValueChangedEventArgs e)
        {
            EventHandler<RDIdentValueChangedEventArgs> temp = RDIdentValueChanged;
            if (temp != null)
            {
                temp(this, e);
            }
        }
    }
}
